データ取得のための React Hooks ライブラリ「SWR」をNext.jsで試してみた
こんにちは!DA(データアナリティクス)事業本部 サービスソリューション部の大高です。
Next.jsと同じチームによって作成されている、データ取得のための React Hooks ライブラリとして「SWR」というライブラリがあります。
今回はこのライブラリの一番基本の部分をNext.jsのプロジェクトで試してみたいと思います。
SWRとは
公式サイトにも以下のように記載されていますが「SWR」という名前はHTTPキャッシュ無効化戦略であるstale-while-revalidate
に由来しています。
“SWR” という名前は、 HTTP RFC 5861 で提唱された HTTP キャッシュ無効化戦略である stale-while-revalidate に由来しています。 SWR は、まずキャッシュからデータを返し(stale)、次にフェッチリクエストを送り(revalidate)、最後に最新のデータを持ってくるという戦略です。
この考え方の仕組みにより、データが高速に返却され、更に自動で再フェッチ(revalidate)されるようになっています。
データの自動再フェッチ(revalidate)に関しては下記のページに詳細が記載されていますが、とても良いですね!
他にも、以下のような特徴を備えています。
- Next.js の SSR / ISR / SSG サポート
- TypeScript 対応
- React Native 対応
実際に試してみる
では、実際に公式のGetting Startedを見ながら試してみたいと思います。
対象プロジェクトの作成
まずはNext.jsのプロジェクトを作成しておきます。プロジェクト名はhello-swr
としました。
% yarn create next-app --typescript yarn create v1.22.17 [1/4] ? Resolving packages... [2/4] ? Fetching packages... [3/4] ? Linking dependencies... [4/4] ? Building fresh packages... success Installed "create-next-app@12.0.7" with binaries: - create-next-app ✔ What is your project named? … hello-swr
インストール
プロジェクトhello-swr
を作成したら、ディレクトリ移動をしてSWRをインストールします。
% cd hello-swr % yarn add swr yarn add v1.22.17 [1/4] ? Resolving packages... [2/4] ? Fetching packages... [3/4] ? Linking dependencies... warning "next > styled-jsx > @babel/plugin-syntax-jsx@7.14.5" has unmet peer dependency "@babel/core@^7.0.0-0". [4/4] ? Building fresh packages... success Saved lockfile. success Saved 1 new dependency. info Direct dependencies └─ swr@1.1.2 info All dependencies └─ swr@1.1.2 ✨ Done in 1.08s.
サンプル作成
インストールしたら、 公式ドキュメントのサンプル「基本的な使用法」を参考に、index.tsx
を以下のように書き換えてサンプルを作成してみます。
import type { NextPage } from "next"; import useSWR from "swr"; import styles from "../styles/Home.module.css"; const fetcher = (url: string) => fetch(url).then((res) => res.json()); const Home: NextPage = () => { const { data, error } = useSWR( "https://api.github.com/repos/vercel/swr", fetcher ); if (error) return <div>An error has occurred.</div>; if (!data) return <div>Loading...</div>; return ( <div className={styles.container}> <main className={styles.main}> <h1 className={styles.title}>{data.name}</h1> <p className={styles.description}>{data.description}</p> <p> <strong>? {data.subscribers_count}</strong>{" "} <strong>✨ {data.stargazers_count}</strong>{" "} <strong>? {data.forks_count}</strong> </p> </main> </div> ); }; export default Home;
このサンプルではhttps://api.github.com/repos/vercel/swr
にリクエストした結果のJSON情報を画面に表示しています。また、リクエスト中にはLoading...
、リクエストエラーの場合にはAn error has occurred.
と表示されるようになっています。
実際に実行すると、このような感じに表示されます。
APIレスポンスが早く、パッと見た感じでは通常のAPI呼び出しと違いが分かりづらいので、少しコードを変えてみます。
import type { NextPage } from "next"; import useSWR from "swr"; import styles from "../styles/Home.module.css"; function sleep(msec: number) { return new Promise((resolve) => { setTimeout(resolve, msec); }); } const fetcher = (url: string) => fetch(url).then(async (res) => { sleep(5000); return res.json(); }); const Home: NextPage = () => { const { data, error } = useSWR( "https://api.github.com/repos/vercel/swr", fetcher ); if (error) return <div>An error has occurred.</div>; if (!data) return <div>Loading...</div>; return ( <div className={styles.container}> <main className={styles.main}> <h1 className={styles.title}>{data.name}</h1> <p className={styles.description}>{data.description}</p> <p> <strong>? {data.subscribers_count}</strong>{" "} <strong>✨ {data.stargazers_count}</strong>{" "} <strong>? {data.forks_count}</strong> </p> </main> </div> ); }; export default Home;
今度は、リクエスト時に5秒ほど待ってからレスポンスを返すようにしてみました。
こちらを試すと、最初の5秒は以下のようにローディング表示がされ、
その後に以下のように表示が自動で切り替わります。
また、このデータがキャッシュされるのでリロードしてもリクエスト結果が変わらない限り、初期表示としてこの画面が即時表示されるようになります。(毎回5秒を待つことはありません)
まとめ
以上、データ取得のための React Hooks ライブラリ「SWR」をNext.jsで試してみました。
今回は一番基本の部分だけでしたが、これだけでもコードの書き方としてかなり楽になると感じました。また、キャッシュ無効化戦略に基づいた仕組みもよく、高速に描画ができるのが良いなと思いました。今後、もう少し別のオプションなども含めて試してみたいと思います。
どなたかのお役に立てば幸いです。それでは!